﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Deeper.Common;
using System.Data;
namespace Deeper.DataAccess
{


	/// <summary>
	/// 表
	/// </summary>
	[AttributeUsageAttribute(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
	public class HTableAttribute : Attribute
	{
		private string strSelect, strUpdate, strDelete, strInsert, strCount;
		/// <summary>
		/// 表ID
		/// </summary>
		public string TableId { set; get; }
		/// <summary>
		/// 表名
		/// </summary>
		public string TableName { set; get; }
		/// <summary>
		/// 实体类名
		/// </summary>
		public string EntityName { set; get; }
		/// <summary>
		/// 表别名
		/// </summary>
		public string TableAlias { set; get; }
		/// <summary>
		/// 中文说明
		/// </summary>
		public string Remake { set; get; }
		/// <summary>
		/// 备注
		/// </summary>
		public string Commont { set; get; }



		/// <summary>
		/// 主键集合
		/// </summary>
		public List<HColumnAttribute> PrimaryKey { get { return Columns.Where(s => s.IsPrimary).ToList(); } }

		/// <summary>
		/// 字段集合
		/// </summary>
		public List<HColumnAttribute> Columns { get; protected set; }

		/// <summary>
		/// 是否整型自增主键
		/// </summary>
		public bool IsIntegerPK { get { return PrimaryKey.Count == 1 && PrimaryKey[0].IsInteger; } }

		public HTableAttribute()
		{
			Columns = new List<HColumnAttribute>();
		}

		#region 生成crud语句
		/// <summary>
		/// 获取select语句
		/// </summary>
		/// <returns></returns>
		public string sqlSelect
		{
			get
			{
				if (strSelect.IsNull())
				{
					String sql = string.Empty;
					foreach (HColumnAttribute dc in Columns)
						sql = string.Format("{1} t.[{0}],", dc.ColumnName, sql);
					sql = string.Format("select {1} from {0} t ", TableName, sql.DelLastComma());
					strSelect = sql;
				}
				return strSelect;
			}
		}
		/// <summary>
		/// 获取插入语句
		/// </summary>
		/// <returns></returns>
		public string sqlInsert
		{
			get
			{
				if (strInsert.IsNull())
				{
					String str = string.Empty;
					String values = string.Empty;
					int pIndex = 0;
					Columns.FindList(dc => !dc.IsIdentity).ToList().ForEach(dc =>
					{
						str = string.Format("{0}{1},", str, dc.ColumnName);
						values = string.Format("{0} @p{1},", values, pIndex++);
					});

					str = string.Format("insert into {0} ({1})  values ({2}) ", TableName, str.ToString().DelLastComma(), values.ToString().DelLastComma());
					strInsert = str;
				}
				return strInsert;
			}
		}
		/// <summary>
		/// 生成更新语句
		/// </summary>
		/// <param name="table">表信息</param>
		/// <returns>返回更新语句</returns>
		public string sqlUpdate
		{
			get
			{
				if (strUpdate.IsNull())
				{
					String str = string.Empty;
					int pIndex = 0;
					Columns.FindList(dc => !dc.IsPrimary).ToList().ForEach(dc =>
					{
						str = string.Format("{0}{1} = @p{2} , ", str, dc.ColumnName, pIndex++);
					});

					str = string.Format("Update {1} set {0} where ", str.ToString().DelLastComma(), TableName);

					PrimaryKey.ForEach(dc =>
					{
						str = string.Format(" {0} {1} = @p{2} and", str, dc.ColumnName, pIndex++);
					});
					strUpdate = str.ToString().DelLastChar(" and");
				}
				return strUpdate;
			}
		}
		/// <summary>
		/// 生成删除语句
		/// </summary>
		public string sqlDelete
		{
			get
			{
				if (strDelete.IsNull())
				{
					String str = string.Empty;
					int pIndex = 0;
					PrimaryKey.ForEach(dc =>
					{
						str = string.Format("{0} {1} = {{{2}}} and", str, dc.ColumnName, pIndex++);
					});
					str = string.Format("delete  {0} where {1} ", TableName, str.ToString().DelLastComma());
					strDelete = str.ToString().DelLastChar(" and");
				}
				return strDelete;
			}
		}
		/// <summary>
		/// 生成Count語句
		/// </summary>
		public string sqlCount
		{
			get
			{
				if (strCount.IsNull())
				{
					strCount = string.Format("select count(1) from {0}", TableName);
				}
				return strCount;
			}
		}
		#endregion

		/// <summary>
		/// 根据datarow获取实体
		/// </summary>
		/// <param name="dr"></param>
		/// <returns></returns>
		public T GetModel<T>(DataRow dr) where T : class,IModel, new()
		{
			try
			{
				T t = new T();
				this.Columns.ForEach(dc =>
				{
					if (!dr.IsNull(dc.ColumnName))///若改列值不为空就反射到实体中
						dc.Field.SetValue(t, Convert.ChangeType(dr[dc.ColumnName], dc.ValueTypeWithNoNullAble), null);
				});
				return t;
			}
			catch (Exception ex)
			{
				throw new DeeperException("转换DataRow到实体出错！", ex);
			}
		}
	}
}
